package com.shenmazong.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shenmazong.order.pojo.TbProduct;
import com.shenmazong.order.service.TbProductService;
import com.shenmazong.order.mapper.TbProductMapper;
import com.shenmazong.utils.ResultResponse;
import com.shenmazong.vo.IdVo;
import com.shenmazong.vo.PageVo;
import com.shenmazong.vo.SearchInfoVo;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 *
 */
@Service
public class TbProductServiceImpl extends ServiceImpl<TbProductMapper, TbProduct>
    implements TbProductService{

    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public ResultResponse add(TbProduct tbProduct) {

        save(tbProduct);
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse listByPage(PageVo pageVo) {
        //--1 分页信息
        Page<TbProduct> page = new Page<>(pageVo.getPageNum(), pageVo.getPageSize());

        //--2 构造查询条件
        QueryWrapper<TbProduct> wrapper = new QueryWrapper<>();
        if(pageVo.getId() != null) {
            // 用户只能查询上架状态的商品
        }
        wrapper.lambda().orderByDesc(TbProduct::getProductId);

        //--3 查询
        Page<TbProduct> tbProductPage = page(page, wrapper);

        // TODO
        //--4 同步到ES中
        // 发送一个MQ消息。消费者接到这个消息后，读取数据，再存入到ES中。

        return ResultResponse.SUCCESS(tbProductPage);
    }

    @Override
    public ResultResponse get(IdVo idVo) {
        //--1
        TbProduct tbProduct = getById(idVo.getId());
        if(tbProduct == null) {
            return ResultResponse.FAILED(404, "没有商品信息");
        }

        //--2
        return ResultResponse.SUCCESS(tbProduct);
    }

    @Override
    public ResultResponse set(TbProduct tbProduct) {
        //--1
        TbProduct product = getById(tbProduct.getProductId());
        if(product == null) {
            return ResultResponse.FAILED(404, "没有商品信息");
        }

        //--2
        tbProduct.setUpdateTime(null);
        tbProduct.setCreateTime(null);

        updateById(tbProduct);

        // TODO
        //--3 同步到ES中
        // 发送一个MQ消息。消费者接到这个消息后，读取数据，再存入到ES中。

        return ResultResponse.SUCCESS();
    }

    /**
     * @description 根据输入的关键字进行高亮搜索
     * @author 军哥
     * @date 2022/8/5 10:35
     * @version 1.0
     */

    @Override
    public ResultResponse searchByWord(SearchInfoVo searchInfoVo) {

        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        //--1 构造分页
        PageRequest page = PageRequest.of(searchInfoVo.getPageNum()-1, searchInfoVo.getPageSize());
        ArrayList<TbProduct> tbProducts = new ArrayList<>();

        //--2 构造查询条件
        if(searchInfoVo.getKeyWord() == null) {
            MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
            builder.withQuery(matchAllQueryBuilder);
        }
        else {
            MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("productName", searchInfoVo.getKeyWord());
            builder.withQuery(queryBuilder);
        }

        //--3 构造高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>").postTags("</font>").field("productName");

        //--4 结果排序
        SortBuilder order = new FieldSortBuilder("productPrice").order(SortOrder.ASC);

        //--5 计算复核条件的记录数

        builder.withPageable(page).withHighlightBuilder(highlightBuilder).withSort(order);
        long count = elasticsearchRestTemplate.count(builder.build(), TbProduct.class);

        //--6
        SearchHits<TbProduct> searchHits = elasticsearchRestTemplate.search(builder.build(), TbProduct.class);

        //--7 获取结果
        List<SearchHit<TbProduct>> hits = searchHits.getSearchHits();
        hits.forEach(item -> {
            // 获取到对象
            TbProduct tbProduct = item.getContent();

            // 获取高亮
            if(item.getHighlightField("productName").size() > 0) {
                String productName = item.getHighlightField("productName").get(0);
                tbProduct.setProductName(productName);
            }

            // 存放结果
            tbProducts.add(tbProduct);
        });

        //--8 对结果进行分页处理
        HashMap<String, Object> map = new HashMap<>();
        map.put("records", tbProducts);
        map.put("total", count);
        map.put("pageNum", searchInfoVo.getPageNum());
        map.put("pageSize", searchInfoVo.getPageSize());
        // 计算页数
        Long pages = 0L;
        if(count%searchInfoVo.getPageSize()>0) {
            pages = count/searchInfoVo.getPageSize() + 1;
        }
        else {
            pages = count/searchInfoVo.getPageSize();
        }
        map.put("pages", pages);

        return ResultResponse.SUCCESS(map);
    }

    @Override
    public ResultResponse searchByRange(SearchInfoVo searchInfoVo) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //--1 构造分页
        PageRequest page = PageRequest.of(searchInfoVo.getPageNum()-1, searchInfoVo.getPageSize());
        ArrayList<TbProduct> tbProducts = new ArrayList<>();

        //--2 构造查询条件
        // 如果区间查询时数值型的话，不要加上忽略大小写
        if(searchInfoVo.getMinPrice() != null) {
            boolQueryBuilder.must(
                    QueryBuilders.rangeQuery("productPrice").gt(searchInfoVo.getMinPrice())
            );
        }
        if(searchInfoVo.getMaxPrice() != null) {
            boolQueryBuilder.must(
                    QueryBuilders.rangeQuery("productPrice").lt(searchInfoVo.getMaxPrice())
            );
        }

        //--4 结果排序
        SortBuilder order = new FieldSortBuilder("productPrice").order(SortOrder.ASC);

        //--5 计算复核条件的记录数
        //
        builder.withPageable(page).withSort(order).withQuery(boolQueryBuilder);

        long count = elasticsearchRestTemplate.count(builder.build(), TbProduct.class);

        //--6
        SearchHits<TbProduct> searchHits = elasticsearchRestTemplate.search(builder.build(), TbProduct.class);

        //--7 获取结果
        List<SearchHit<TbProduct>> hits = searchHits.getSearchHits();
        hits.forEach(item -> {
            // 获取到对象
            TbProduct tbProduct = item.getContent();

            // 存放结果
            tbProducts.add(tbProduct);
        });

        //--8 对结果进行分页处理
        HashMap<String, Object> map = new HashMap<>();
        map.put("records", tbProducts);
        map.put("total", count);
        map.put("pageNum", searchInfoVo.getPageNum());
        map.put("pageSize", searchInfoVo.getPageSize());
        // 计算页数
        Long pages = 0L;
        if(count%searchInfoVo.getPageSize()>0) {
            pages = count/searchInfoVo.getPageSize() + 1;
        }
        else {
            pages = count/searchInfoVo.getPageSize();
        }
        map.put("pages", pages);

        return ResultResponse.SUCCESS(map);
    }
}




